import numpy as np

# 详细讲解网址：http://keep.01ue.com/?pi=370864&_a=app&_c=index&_m=p

def covariance(X, Y):
    """
    计算两个等长向量的协方差
    :param X:
    :param Y:
    :return:
    """
    n = np.shape(X)[0]
    X, Y = np.array(X), np.array(Y)
    meanX, meanY = np.mean(X), np.mean(Y)
    cov = np.sum(np.multiply(X-meanX, Y-meanY)) / (n-1)
    return cov


def calcCov1(samples): # 方法1：根据协方差公式和协方差矩阵的概念计算协方差矩阵
    n = np.shape(samples)[1] # shamples的特征总数
    covMat = []  # 保存求得的协方差矩阵
    covMat = np.full((n, n), fill_value=0.)
    for i in range(n):
        for j in range(n):
            covMat[i ,j] = covariance(samples[:, i], samples[:, j]) # 这里是以列为一个数据
    return covMat


def calcCov2(samples):
    n = np.shape(samples)[0] # 样例总数
    mean = []
    covMat = []
    for atter in samples.T:
        mean.append(np.mean(atter))
    #print(mean)
    #mean = np.array([np.mean(attr) for attr in samples.T])  # 样本集的特征均值
    centrS = samples - mean  ##样本集的中心化
    #print("每个元素将去当前维度特征的均值：", centrS)
    covMat = np.dot(centrS.T, centrS) / (n-1)
    return covMat


if __name__ == '__main__':
    '10样本3特征的样本集'
    samples = np.array([[10, 15, 29],
                        [15, 46, 13],
                        [23, 21, 30],
                        [11, 9, 35],
                        [42, 45, 11],
                        [9, 48, 5],
                        [11, 21, 14],
                        [8, 5, 15],
                        [11, 12, 21],
                        [21, 20, 25]])
    covXY1 = calcCov1(samples)
    print(covXY1)
    covXY2 = np.cov(samples.T) # cov()方法是默认以一个行为数据
    print(covXY2)
    covXY3 = calcCov2(samples)
    print(covXY3)